﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Cleverscape.UTorrentClient.WebClient;
using GalaSoft.MvvmLight.Threading;

namespace Cleverscape.UTorrentClient.WebClient
{
    /// <summary>
    /// Represents a Feed currently active within uTorrent
    /// </summary>
    public class Feed : INotifyPropertyChanged
    {

        #region Private Fields

        //private DateTime _filesLastUpdated;
        //private DateTime _propertiesLastUpdated;

        internal FeedCollection ParentCollection;
        private FeedItemCollection _feedItems;

        private int _ident;
        private bool _enabled;
        private bool _useFeedTitle;
        private bool _userSelected;
        private bool _programmed;
        private int _downloadState;
        private string _url;
        private string _alias;
        private int _nextUpdate;

        #endregion

        #region Constructor

        internal Feed(object[] InputValues, FeedCollection ParentCollection)
        {
            this.ParentCollection = ParentCollection;
            this._feedItems = new FeedItemCollection(this.ParentCollection.ParentClient);
            UpdateValuesFromStringArray(InputValues, true);
        }

        public Feed()
        {
            this.Url = "http://www.testrssurl.com/?blaw&super&blaw&yadayadayada";
            this.Alias = "My RSS Feed Alias";
        }

        internal bool UpdateValuesFromStringArray(object[] InputValues)
        {
            return UpdateValuesFromStringArray(InputValues, false);
        }

        private bool UpdateValuesFromStringArray(object[] InputValues, bool NewFeed)
        {
            bool ReturnChanged = false;
            //bool CallFinishedDownloading = false;
            //bool CallStarted = false;
            //bool CallStopped = false;
            //bool CallPaused = false;
            //bool CallUnPaused = false;
            if (InputValues.Length != 9)
            {
                throw new FormatException("The array of feed data was not in the expected format.");
            }
            if (Ident != (int)InputValues[0])
            {
                Ident = (int)InputValues[0];
                ReturnChanged = true;
            }
            if (Enabled != (bool)InputValues[1])
            {
                Enabled = (bool)InputValues[1];
                ReturnChanged = true;
            }
            if (UseFeedTitle != (bool)InputValues[2])
            {
                UseFeedTitle = (bool)InputValues[2];
                ReturnChanged = true;
            }
            if (UserSelected != (bool)InputValues[3])
            {
                UserSelected = (bool)InputValues[3];
                ReturnChanged = true;
            }
            if (Programmed != (bool)InputValues[4])
            {
                Programmed = (bool)InputValues[4];
                ReturnChanged = true;
            }
            if (DownloadState != (int)InputValues[5])
            {
                DownloadState = (int)InputValues[5];
                ReturnChanged = true;
            }
            string[] UrlAlias = InputValues[6].ToString().Split('|');
            if (UrlAlias.Length == 2)
            {
                if (Alias != UrlAlias[0])
                {
                    Alias = UrlAlias[0];
                    ReturnChanged = true;
                }
                if (Url != UrlAlias[1])
                {
                    Url = UrlAlias[1];
                    ReturnChanged = true;
                }
            }
            else
            {
                if (Url != UrlAlias[0])
                {
                    Url = UrlAlias[0];
                    ReturnChanged = true;
                }
                if (Alias != "")
                {
                    Alias = "";
                    ReturnChanged = true;
                }
            }
            if (Url != (string)InputValues[6])
            {
                Url = (string)InputValues[6];
                ReturnChanged = true;
            }
            if (NextUpdate != (int)InputValues[7])
            {
                NextUpdate = (int)InputValues[7];
                ReturnChanged = true;
            }
            if (NewFeed)
            {
                foreach (object[] feedItem in (object[])InputValues[8])
                {
                    FeedItem fItem = new FeedItem(feedItem);
                    this._feedItems.Add(fItem);
                }
            }
            else
            {

                List<FeedItem> removedFIs = new List<FeedItem>();
                removedFIs.AddRange(this._feedItems);
                foreach (object[] feedItem in (object[])InputValues[8])
                {

                    FeedItem foundItem = this._feedItems.GetByName((string)feedItem[0]);
                    if (foundItem != null)
                    {
                        removedFIs.Remove(foundItem);
                        foundItem.UpdateValues(feedItem);
                        
                    }
                    else
                    {
                        FeedItem fItem = new FeedItem(feedItem);
                        this._feedItems.Add(fItem);
                    }


                }
                //Remove feed items not found
                foreach (FeedItem rFI in removedFIs)
                {
                    this._feedItems.Remove(rFI);
                }
            }
           
            //if (CallFinishedDownloading)
            //{
            //    ParentCollection.ParentClient.CallEvent(UTorrentWebClient.EventType.FinishedDownloading, this);
            //}
            //if (CallPaused)
            //{
            //    ParentCollection.ParentClient.CallEvent(UTorrentWebClient.EventType.Paused, this);
            //}
            //if (CallUnPaused)
            //{
            //    ParentCollection.ParentClient.CallEvent(UTorrentWebClient.EventType.UnPaused, this);
            //}
            //if (CallStarted)
            //{
            //    ParentCollection.ParentClient.CallEvent(UTorrentWebClient.EventType.Started, this);
            //}
            //if (CallStopped)
            //{
            //    ParentCollection.ParentClient.CallEvent(UTorrentWebClient.EventType.Stopped, this);
            //}
            return ReturnChanged;
        }

        

        #endregion

        #region Public Methods (Overriden from object)

        public override bool Equals(object obj)
        {
            return (obj is Feed) && ((Feed)obj).Ident == this.Ident;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        

        

        #endregion

        #region Public Events (INotifyPropertyChanged)

        /// <summary>
        /// Event to notify when a property of the torrent has changed
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string PropertyName)
        {

            if (DispatcherHelper.UIDispatcher != null)
            {
                DispatcherHelper.UIDispatcher.BeginInvoke(() =>
                {
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
                    }
                });
            }
            else
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
                }
            }
            
        }

        #endregion

        

        

        #region Public Properties (Basic Torrent Properties)

        
        public int Ident
        {
            get
            {
                return _ident;
            }
            private set
            {
                _ident = value;
                NotifyPropertyChanged("Ident");
            }
        }

        
        public bool Enabled
        {
            get
            {
                return _enabled;
            }
            set
            {
                _enabled = value;
                NotifyPropertyChanged("Enabled");
            }
        }

        public bool UseFeedTitle
        {
            get
            {
                return _useFeedTitle;
            }
            set
            {
                _useFeedTitle = value;
                NotifyPropertyChanged("UseFeedTitle");
            }
        }
        public bool UserSelected
        {
            get
            {
                return _userSelected;
            }
            set
            {
                _userSelected = value;
                NotifyPropertyChanged("UserSelected");
            }
        }
        public bool Programmed
        {
            get
            {
                return _programmed;
            }
            set
            {
                _programmed = value;
                NotifyPropertyChanged("Programmed");
            }
        }

        public int DownloadState
        {
            get
            {
                return _downloadState;
            }
            private set
            {
                _downloadState = value;
                NotifyPropertyChanged("DownloadState");
            }
        }

        public string Url
        {
            get
            {
                return _url;
            }
            set
            {
                _url = value;
                NotifyPropertyChanged("Url");
            }
        }

        public string Alias
        {
            get
            {
                return _alias;
            }
            set
            {
                _alias = value;
                NotifyPropertyChanged("Alias");
            }
        }

        private Filter SubscribeFilter
        {
            get
            {
                if (this.Ident == 0)
                    return null;
                var subFilter = from mFilter in this.ParentCollection.ParentClient.Filters
                                where (mFilter.Name == this.Alias || mFilter.Name == this.Url) && mFilter.FilterText == "*" && mFilter.Enabled == true && mFilter.Feed == this.Ident
                                select mFilter;
                foreach (Filter mf in subFilter)
                {
                    return mf;
                }
                return null;
            }
        }

        public bool Subscribed
        {
            get
            {
                
                return (SubscribeFilter != null) ? true : false;
            }
            set
            {
                if (value)
                {
                    if (this.SubscribeFilter == null)
                    {
                        if (this.Ident == 0)
                            return;
                        Filter newSubscribeFilter = new Filter();
                        newSubscribeFilter.Feed = this.Ident;
                        newSubscribeFilter.Name = (this.Alias.Length > 0) ? this.Alias : this.Url;
                        newSubscribeFilter.FilterText = "*";
                        newSubscribeFilter.Update();
                    }
                }
                else
                {
                    if (this.SubscribeFilter != null)
                    {
                        this.ParentCollection.ParentClient.Filters.Remove(this.SubscribeFilter);
                    }
                }
            }
        }
        public bool SmartEpFilter
        {
            get
            {
                if (this.SubscribeFilter != null)
                    return this.SubscribeFilter.SmartEpFilter;
                else
                    return false;
            }
            set
            {
                if (this.SubscribeFilter != null)
                {
                    this.SubscribeFilter.SmartEpFilter = value;
                    this.SubscribeFilter.Update();
                }
            }

        }

        public int NextUpdate
        {
            get
            {
                return _nextUpdate;
            }
            private set
            {
                _nextUpdate = value;
                NotifyPropertyChanged("NextUpdate");
            }
        }

        #endregion

        #region Public Properties (Collections)

        /// <summary>
        /// The collection of files that make up the torrent.
        /// Note: Accessing this property will call the uTorrent web interface to update the list of files for this torrent if it hasn't been updated recently.
        /// </summary>
        public FeedItemCollection FeedItems
        {
            get
            {
                return _feedItems;
            }
        }

        #endregion

        #region Public Methods 

        

        /// <summary>
        /// Remove the feed
        /// </summary>
        public void Remove()
        {
            ParentCollection.ParentClient.FeedRemove(this);
        }

        /// <summary>
        /// Update the feed
        /// </summary>
        public void Update()
        {
            ParentCollection.ParentClient.FeedUpdateAdd(this);
        }

        #endregion

        
    }

 
}
